package com.bdqn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdqn.mapper.SysRoleMapper;
import com.bdqn.mapper.SysRoleRightMapper;
import com.bdqn.pojo.SysRole;
import com.bdqn.pojo.SysRoleRight;
import com.bdqn.service.SysRoleService;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author LILIBO
 * @description 针对表【sys_role】的数据库操作Service实现
 * @createDate 2025-03-26 08:54:56
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Resource
    private SysRoleRightMapper sysRoleRightMapper;

    /**
     * 分页查询角色列表
     *
     * @param roleName
     * @param page
     * @return
     * @Cacheable 首先查缓存有就返回，没有就执行方法，方法返回不为空添加缓存
     * value: 缓存名称，可以多个
     * key: 缓存的键值
     * keyGenerator = "keyGenerator": 缓存的key自动生成
     * condition: 满足条件的调用，结果才会被缓存（不指定时相当于true-缓存）
     * unless: 不合适的返回，结果不缓存（不指定时相当于false-缓存）
     * 总结: 当condition=false一定不缓存；当condition=true且unless=true不缓存；当condition=true且unless=false缓存
     */
    @Override
    @Cacheable(value = "sysrole", key = "'page:' + #page.current + '-' + #page.size + '-' + #roleName", condition = "#page.current!=null and #page.size!=null", unless = "#result==null")
    public Page<SysRole> queryPage(String roleName, Page<SysRole> page) {
        // 构建查询条件
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        if (roleName != null) {
            qw.like(SysRole :: getRoleName, roleName);
        }
        return super.page(page, qw);
    }

    /**
     * 检查用户名是否存在（排除本身ID）
     *
     * @param roleName
     * @param roleId
     * @return
     */
    @Override
    public String check(String roleName, Long roleId) {
        if (roleName == null || roleName.isEmpty()) {
            return "error";
        }
        // 使用LambdaQueryWrapper避免写死字段名
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        qw.eq(SysRole :: getRoleName, roleName);
        if (roleId != null) {
            qw.ne(SysRole :: getRoleId, roleId);
        }
        SysRole sysRole = baseMapper.selectOne(qw);

        return sysRole != null ? "false" : "true";
    }

    /**
     * 保存角色信息（兼容添加和修改，并且处理权限关联关系）
     *
     * @param sysRole
     * @param rightCodes
     * @return
     * @CachePut 首先执行方法体，执行完毕后根据参数设置进行缓存覆盖
     * value: 缓存名称
     * key: 缓存的键值
     * condition: 满足条件的调用，结果才会被缓存（不指定时相当于true-缓存）
     * unless: 不合适的返回，结果不缓存（不指定时相当于false-缓存）
     * 总结: 当condition=false一定不缓存；当condition=true且unless=true不缓存；当condition=true且unless=false缓存
     */
    @Override
    @Transactional // 事务管理
    @CachePut(value = "sysrole", key = "'roleId:' + #sysRole.roleId", condition = "#sysRole!=null", unless = "#result==null")
    @Caching(evict = {@CacheEvict(value = "sysrole", allEntries = true), @CacheEvict(value = "sysuser", allEntries = true)}) // 清除多个缓存
    public SysRole saveSysRole(SysRole sysRole, String[] rightCodes) {
        // 2 客户经理 {"L01","L0101","L0102","L02","L0201","L0202"}
        if (sysRole == null || rightCodes == null) {
            return null;
        }
        // 保存角色信息
        boolean saveOrUpdate = super.saveOrUpdate(sysRole);
        if (!saveOrUpdate) {
            return null;
        }
        // 处理权限关联关系
        QueryWrapper<SysRoleRight> qw = new QueryWrapper<>();
        qw.eq("rf_role_id", sysRole.getRoleId());
        sysRoleRightMapper.delete(qw); // 删除原有的权限关联关系

        /* int a = 10;
        if (a > 0) {
            // 模拟一个异常（@Transactional 开启事务，方法抛出异常时将会回滚）
            throw new RuntimeException("模拟一个异常");
        } */

        // 将rightCodes中的角色编号与角色对应保存
        List<SysRoleRight> sysRoleRights = new ArrayList<>();
        for (String rightCode : rightCodes) {
            sysRoleRights.add(new SysRoleRight(sysRole.getRoleId(), rightCode));
        }
        // 再批量添加角色权限对应数据
        sysRoleRightMapper.insert(sysRoleRights);
        return sysRole;
    }

}




